// Copyright (c) 2009, Philip Tucker
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the <organization> nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY Philip Tucker 'AS IS' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL Philip Tucker BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.honkentuber.android;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Location;
import android.util.Log;


/**
 * Collects all active locations, homeItem and search results.
 */
public class MapItems {
  private final static String LOG_ID = MapItems.class.getSimpleName();

  private final String homeTitle;
  
  private final Drawable homeMarker;
  
  private final int homeType;
  
  private final Locale locale;
  
  private class HomeItem implements MapItem {
    private final Address address;
    
    public HomeItem(Location location) {
      address = new Address(locale);
      address.setLatitude(location.getLatitude());
      address.setLongitude(location.getLongitude());
      address.setFeatureName(homeTitle);
    }
    
    @Override
    public Address getAddress() {
      return address;
    }

    @Override
    public int getType() {
      return homeType;
    }

    @Override
    public String getTitle() {
      return address.getFeatureName();
    }

    @Override
    public Drawable getMarker() {
      return homeMarker;
    }

    @Override
    public String toString() {
      return address.getFeatureName();
    }
  }

  /**
   * We use this to avoid collisions. We do not allow 2 game locations with the
   * same lat/lon.
   */
  private final Set<String> addressHashes = new HashSet<String>();

  private final List<MapSearch> searches = new ArrayList<MapSearch>();
  
  private HomeItem homeItem = null;
  
  public MapItems(String homeTitle, Drawable homeMarker, int homeType, 
      Locale locale) {
    this.homeTitle = homeTitle;
    this.homeMarker = homeMarker;
    this.homeType = homeType;
    this.locale = locale;
  }

  /**
   * @param address Address to add.
   * @return True if this address was added, false if it's already been added.
   */
  public boolean addSearchResult(Address address) {
    Log.v(LOG_ID, "addSearchResult: " + Geo.toLatLonE6String(address) 
        + ", " + Geo.toShortName(address));
    
    // TODO(ptucker) looser hash, wider range of collision?
    String hash = Geo.toLatLonE6String(address);
    
    if (addressHashes.contains(hash)) {
      return false;
    }

    addressHashes.add(hash);
    return true;
  }

  public void resetSearch() {
    addressHashes.clear();
    for (MapSearch search : searches) {
      search.reset();
    }
  }

  public void addSearch(int id, String title, Drawable marker, 
      List<String> queries) {
    MapSearch search = new MapSearch(id, title, marker, queries, this);
    searches.add(search);
  }
  
  public List<MapSearch> getSearches() {
    return Collections.unmodifiableList(searches);
  }

  public MapItem getHomeItem() {
    return homeItem;
  }
  
  /**
   * @param location New homeItem location.
   * @return Home location.
   */
  public MapItem setHomeLocation(Location location) {
    homeItem = new HomeItem(location);
    return homeItem;
  }
}
